//
// Created on 2025/6/9.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".

#include "queue.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "hilog/log.h"
#include <errno.h>

// 初始化消息队列
void mq_init(MessageQueue* queue) {
    queue->head = NULL;
    queue->tail = NULL;
    pthread_mutex_init(&queue->lock, NULL);
    pthread_cond_init(&queue->cond, NULL);
    queue->shutdown = 0;
}

// 销毁消息队列
void mq_destroy(MessageQueue* queue) {
    pthread_mutex_lock(&queue->lock);
    queue->shutdown = 1;
    pthread_cond_broadcast(&queue->cond);
    pthread_mutex_unlock(&queue->lock);

    Message* msg = mq_try_receive(queue);
    while (msg != NULL) {
        mq_free_message(msg);
        msg = mq_try_receive(queue);
    }

    pthread_mutex_destroy(&queue->lock);
    pthread_cond_destroy(&queue->cond);
}

// 发送消息（异步）
void mq_send(MessageQueue* queue, int type, void* data, size_t data_size) {
    Message* msg = (Message*)malloc(sizeof(Message));
    if (!msg) {
        perror("Failed to allocate message");
        return;
    }

    msg->type = type;
    msg->data_size = data_size;
    
    if (data && data_size > 0) {
        msg->data = malloc(data_size);
        if (!msg->data) {
            perror("Failed to allocate message data");
            free(msg);
            return;
        }
        memcpy(msg->data, data, data_size);
    } else {
        msg->data = NULL;
    }
    
    msg->next = NULL;

    pthread_mutex_lock(&queue->lock);
    
    if (queue->shutdown) {
        pthread_mutex_unlock(&queue->lock);
        mq_free_message(msg);
        return;
    }

    if (!queue->tail) {
        queue->head = queue->tail = msg;
    } else {
        queue->tail->next = msg;
        queue->tail = msg;
    }

    pthread_cond_signal(&queue->cond);
    pthread_mutex_unlock(&queue->lock);
}

// 接收消息（阻塞）
Message* mq_receive(MessageQueue* queue) {
    
    
   // OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "Udp_recv", "mq_receive 1-1");
    struct timespec ts;
    clock_gettime(CLOCK_REALTIME, &ts);  // 获取当前时间
    ts.tv_sec += 0;  
    
    ts.tv_nsec  += 100000000;  // 设置 100 毫秒的超时时间
    
    if(ts.tv_nsec >= 1000000000){
        ts.tv_sec += 1;
        
        ts.tv_nsec = ts.tv_nsec - 1000000000;
    }
    
    pthread_mutex_lock(&queue->lock);
    
    while (!queue->head && !queue->shutdown) {
       // OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "Udp_recv", "mq_receive 1");
        int res = pthread_cond_timedwait(&queue->cond, &queue->lock, &ts);
      //  OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "Udp_recv", "mq_receive 1-2 res = %{public}d  ts.ns= %{public}d", res, ts.tv_nsec);
        {
             if (res == ETIMEDOUT) 
             {
                pthread_mutex_unlock(&queue->lock);
                return NULL;
             }
        }
    }

    if (queue->shutdown && !queue->head) {
        pthread_mutex_unlock(&queue->lock);
        return NULL;
    }
  //  OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "Udp_recv", "mq_receive 2");
    Message* msg = queue->head;
    if (msg) {
        queue->head = msg->next;
        if (!queue->head) {
            queue->tail = NULL;
        }
    }
 //   OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "Udp_recv", "mq_receive 3");
    pthread_mutex_unlock(&queue->lock);
    return msg;
}

// 非阻塞接收消息
Message* mq_try_receive(MessageQueue* queue) {
    pthread_mutex_lock(&queue->lock);
    
    Message* msg = queue->head;
    if (msg) {
        queue->head = msg->next;
        if (!queue->head) {
            queue->tail = NULL;
        }
    }
    
    pthread_mutex_unlock(&queue->lock);
    return msg;
}

// 释放消息内存
void mq_free_message(Message* msg) {
    if (msg) {
        if (msg->data) {
            free(msg->data);
        }
        free(msg);
    }
}    